#ifndef GAMEWORLD_H
#define GAMEWORLD_H

#include <list>
#include "cPlayer.h"
#include "cEnemyFactory.h"
#include "cItemFactory.h"
#include "cObstacleFactory.h"
#include "Level.h"
#include "CController.h"

//Constants for the Game World
#define TIME_TO_UPDATE		1.00F
#define MAX_FPS				60.0F
#define MAX_SPEED			5.0F
#define MAX_ACCELERATION	10.0F
#define MAX_VELOCITY		25.0F
#define MAX_DOORS			4

class GameWorld
{
	public:
		//Creates the game world for the player
		GameWorld();
		~GameWorld();
		
		//Information for initializing the game world
		void initWorld();

		//Provides the information for updating 
		//the collision test, player input
		void updateWorld(float dt);

		//Method for moving projectiles inside of the game
		//world
		void moveProjectiles();

		//Method for moving objects inside of the game world
		void moveObjects();

		//Method for moving enemies inside of the game world
		void moveEnemies();
		 
		//Method for Spatial Indexing for collision detection, this
		//will provide information as to the distance of each object
		//which will allow resolutions to be performed efficiently
		void SpatialTesting();

		//Method for testing to see if the player is colliding with
		//a  wall to stop them from going out of bounds
	
		//Method for resolving if the player was touched by an enemy
		
		//Method for resolving if the player touched a crypt
		bool isTouchingCrypt();

		//Method for the player picking up an item and storing
		//the item into the inventory system
		void PickupItem();

		//Method for the player to drop an item from the inventory
		//system
		void DropItem();

		//Method for resolving if a projectile touches a tombstone
		void DestroyTombstone();

		//Method for openning a crypt 
		void OpenCrypt();

		//Method for releaeing an item from the crypt
		void ReleaseItemFromCrypt();

		//Method for spawning enemies into a room
		void SpawnEnemies();

		//Method for spawning objects into a room
		void SpawnObjects();

		//Method for enemies dropping an potion
		void DropPotion();

		//Method for interacting with a fountain
		void TouchFountain();

		//Method for transitioning between rooms
		void changeRoom();

		//Method for transitiioning between levels
		void nextLevel();

		//Method for Calculating the combat damage/plain damage in the
		//game.

		//Performs a check on the winning and losing conditions
		//of the game
		bool isGameOver();
		bool isGameWin();

		//Returns the information of the player 
		//in order to be rendered to the screen
		cPlayer*	getPlayer() { return m_pPlayer; }

		//Returns the information of the rock
		//
		cRock*		getRock() { return m_pRock; }

		//Returns the information of the room
		//in order to be rendered to the screen
		Room*		getRoom() { return m_pCurrentRoom; }

		//Returns the object list to render onto the screen
		std::list<cEnemy> getEnemyList() { return m_enemyList; }

		//Returns the enemy list to render ontom the screen
		std::list<cProjectile> getProjectileList() { return m_projectileList; }

		//Returns the Object List
		std::list<cStaticObject> getObjectList() { return m_objectList; }
		
	private:
		//Holds the information related to the level
		Level						*m_currentLevel;

		//Holds the information related to the current room
		Room						*m_pCurrentRoom;
		
		//Holds the information related to the player
		cPlayer						*m_pPlayer;
		cEnemyFactory				*m_pEFactory;
		cObstacleFactory			*m_pOFactory;
		cItemFactory				*m_pIFactory;
		cRock						*m_pRock;
		cDoor						*m_pDoor;

		//Interface for testing collision detection
		cOverlapTest				*m_pContactTest;
		bool						m_bHasContactedX;
		bool						m_bHasContactedY;

		//Controls the information of the objects in the room
		unsigned int				m_numberOfObjects;
		unsigned int				m_numberOfWalls;
		unsigned int				m_numberOfDoors;

		//Controls the player inventory setup

		//Holds the information related to the list
		std::list<cEnemy>			m_enemyList;
		std::list<cProjectile>		m_projectileList;
		std::list<cStaticObject>	m_objectList;
		std::list<AABB>				m_boundList;

		//Game conditions
		bool						m_bIsGameOver;
		bool						m_bIsGameWin;
};
#endif